<?php
	/**
	 *  PHP class for downloading CSV files from Google Webmaster Tools.
	 *
	 *  This class does NOT require the Zend gdata package be installed
	 *  in order to run.
	 *
	 *  Copyright 2012 eyecatchUp UG. All Rights Reserved.
	 *
	 *  Licensed under the Apache License, Version 2.0 (the "License");
	 *  you may not use this file except in compliance with the License.
	 *  You may obtain a copy of the License at
	 *
	 *     http://www.apache.org/licenses/LICENSE-2.0
	 *
	 *  Unless required by applicable law or agreed to in writing, software
	 *  distributed under the License is distributed on an "AS IS" BASIS,
	 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	 *  See the License for the specific language governing permissions and
	 *  limitations under the License.
	 *
	 *  @author: Stephan Schmitz <eyecatchup@gmail.com>
	 */

	 class GWTdata
	 {

		const APP_NAME   = "Google-WMTdownloadscript-0.1-php";
		const HOST       = "https://www.google.com";
		const LOGIN_PATH = "/accounts/ClientLogin";
		const SITES_PATH = "/webmasters/tools/feeds/sites/";
		const LIST_PATH  = "/webmasters/tools/downloads-list?hl=%s&siteUrl=%s";

		private $_auth, $logged_in;
		public $_language, $_downloaded;

		public function __construct()
		{
			$this->_auth = false;
			$this->_logged_in = false;
			$this->_language = "en";
			$this->_downloaded = array();
		}

		/**
		 *  Check if client has logged into their Google account yet.
		 *  @return Boolean  Returns true if logged in to a Google account,
		 *                   or false if not.
		 */
			private function IsLoggedIn()
			{
				return $this->_logged_in;
			}

		/**
		 *  Attempts to log into the specified Google account.
		 *
		 *  @param $email  String   User's Google email address.
		 *  @param $pwd    String   Password for Google account.
		 *  @return Boolean  Returns true when Authentication was successful,
		 *                   else false.
		 */
			public function LogIn($email, $pwd)
			{
				$url = self::HOST . self::LOGIN_PATH;
				$postRequest = array(
					'accountType' => 'HOSTED_OR_GOOGLE',
					'Email' => $email,
					'Passwd' => $pwd,
					'service' => "sitemaps",
					'source' => 'Google-WMTdownloadscript-0.1'
				);
				$ch = curl_init();
				curl_setopt($ch, CURLOPT_URL, $url);
				curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
				curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
				curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
				curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
				curl_setopt($ch, CURLOPT_POST, true);
				curl_setopt($ch, CURLOPT_POSTFIELDS, $postRequest);
				$output = curl_exec($ch);
				$info = curl_getinfo($ch);
				curl_close($ch);
				if($info['http_code'] == 200) {
					preg_match('/Auth=(.*)/', $output, $match);
					if(isset($match[1])) {
						$this->_auth = $match[1];
						$this->_logged_in = true;
						return true;
					} else { return false; }
				}
				return false;
			}

		/**
		 *  Gets all available sites from Google Webmaster Tools account.
		 *
		 *  @return Mixed  Array with all site URLs registered in GWT account,
		 *                 or false (Boolean) when Authentication fails.
		 */
			public function GetSites()
			{
				if(self::IsLoggedIn() === true) {
					$feed = self::GetData(self::SITES_PATH);
					if(is_numeric($feed)) {
						return false;
					} else {
						$sites = array();
						$doc = new DOMDocument();
						$doc->loadXML($feed);
						foreach ($doc->getElementsByTagName('entry') as $node) {
							array_push($sites,
								$node->getElementsByTagName('title')->item(0)->nodeValue);
						}
						return $sites;
					}
				} else { return false; }
			}

		/**
		 *  Gets the download links for an available site
		 *  from the Google Webmaster Tools account.
		 *
		 *  @param $url    String   Site URL registered in GWT.
		 *  @return Mixed  Array with keys TOP_PAGES and TOP_QUERIES,
		 *                 or false (Boolean) when Authentication fails.
		 */
			public function GetDownloadUrls($url)
			{
				if(self::IsLoggedIn() === true) {
					$_url = sprintf(self::LIST_PATH,
						$this->_language,
						urlencode($url));
					$downloadList = self::GetData($_url);
					return json_decode($downloadList, true);
				} else { return false; }
			}

		/**
		 *  Attempts an authenticated GET Request.
		 *
		 *  @param $url    String   URL for the GET request.
		 *  @return Mixed  Curl result as String,
		 *                 or false (Boolean) when Authentication fails.
		 */
			public function GetData($url)
			{
				if(self::IsLoggedIn() === true) {
					$url = self::HOST . $url;
					$head = array("Authorization: GoogleLogin auth=".$this->_auth,
						"GData-Version: 2");
					$ch = curl_init();
					curl_setopt($ch, CURLOPT_URL, $url);
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
					curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
					curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
					curl_setopt($ch, CURLOPT_HTTPHEADER, $head);
					$result = curl_exec($ch);
					$info = curl_getinfo($ch);
					curl_close($ch);
					return ($info['http_code']!=200) ? $info['http_code'] : $result;
				} else { return false; }
			}

		/**
		 *  Downloads the file based on the given URL.
		 *
		 *  @param $site    String   Site URL available in GWT Account.
		 *  @param $savepath  String   Optional path to save CSV to (no trailing slash!).
		 */
			public function DownloadCSV($site, $savepath=".")
			{
				if(self::IsLoggedIn() === true) {
					$downloadUrls = self::GetDownloadUrls($site);
					$filename = parse_url($site, PHP_URL_HOST) ."-". date("Ymd-His");
					if(file_put_contents("$savepath/TOP_PAGES-$filename.csv",
						self::GetData($downloadUrls["TOP_PAGES"] .
							"&prop=ALL&region&more=true"))) {
						array_push($this->_downloaded,
							realpath("$savepath/TOP_PAGES-$filename.csv"));
					}
					if(file_put_contents("$savepath/TOP_QUERIES-$filename.csv",
						self::GetData($downloadUrls["TOP_QUERIES"] .
							"&prop=ALL&region&more=true"))) {
						array_push($this->_downloaded,
							realpath("$savepath/TOP_QUERIES-$filename.csv"));
					}
				} else { return false; }
			}

		/**
		 *  Returns an array of downloaded filenames.
		 *
		 *  @return  Array   Array of filenames that have been written to disk.
		 */
			public function GetDownloadedFiles()
			{
				return $this->_downloaded;
			}

		/**
		 *  Sets the content language.
		 *
		 *  @param $str     String   Valid ISO 639-1 language code, supported by Google.
		 */
			public function SetLanguage($str)
			{
				$this->_language = $str;
			}
	 }
?>